/*
 * GraphSView.java
 */

package interfaz;

import analizador.*;
import dominio.*;
import javax.swing.text.BadLocationException;
import utilidades.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 * The application's main frame.
 */

public class GraphSView extends FrameView {

    private boolean grafoModificado = false;
    private final String title = "GraphS - ";
    private File fileGraph = null;
    private final int YES_OP = 0;
    private final int NO_OP = 1;
    private final int CANCEL_OP = 2;

    public GraphSView(SingleFrameApplication app) {
        super(app);

        initComponents();

        procesadorTextArea.setTabSize(4);
        statusMessageLabel.setText("1:1");
        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = GraphSApp.getApplication().getMainFrame();
            aboutBox = new GraphSAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        GraphSApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        toolBar = new javax.swing.JToolBar();
        newButton = new javax.swing.JButton();
        openButton = new javax.swing.JButton();
        saveButton = new javax.swing.JButton();
        saveAsButton = new javax.swing.JButton();
        jSeparator5 = new javax.swing.JToolBar.Separator();
        cutButton = new javax.swing.JButton();
        copyButton = new javax.swing.JButton();
        pasteButton = new javax.swing.JButton();
        jSeparator6 = new javax.swing.JToolBar.Separator();
        compileButton = new javax.swing.JButton();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        procesadorTextArea = new javax.swing.JTextArea();
        jScrollPane2 = new javax.swing.JScrollPane();
        realimentacionTextArea = new javax.swing.JTextArea();
        jToggleButton1 = new javax.swing.JToggleButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        newMenuItem = new javax.swing.JMenuItem();
        openMenuItem = new javax.swing.JMenuItem();
        saveMenuItem = new javax.swing.JMenuItem();
        saveAsMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        compileMenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JSeparator();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        cutMenuItem = new javax.swing.JMenuItem();
        copyMenuItem = new javax.swing.JMenuItem();
        pasteMenuItem = new javax.swing.JMenuItem();
        deleteMenuItem = new javax.swing.JMenuItem();
        jSeparator4 = new javax.swing.JSeparator();
        selectAllMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        userManualMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setMaximumSize(new java.awt.Dimension(450, 350));
        mainPanel.setMinimumSize(new java.awt.Dimension(450, 350));
        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setPreferredSize(new java.awt.Dimension(450, 200));

        toolBar.setFloatable(false);
        toolBar.setRollover(true);
        toolBar.setName("toolBar"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(interfaz.GraphSApp.class).getContext().getResourceMap(GraphSView.class);
        newButton.setIcon(resourceMap.getIcon("newButton.icon")); // NOI18N
        newButton.setText(resourceMap.getString("newButton.text")); // NOI18N
        newButton.setToolTipText(resourceMap.getString("newButton.toolTipText")); // NOI18N
        newButton.setFocusable(false);
        newButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        newButton.setName("newButton"); // NOI18N
        newButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        newButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newButtonActionPerformed(evt);
            }
        });
        toolBar.add(newButton);

        openButton.setIcon(resourceMap.getIcon("openButton.icon")); // NOI18N
        openButton.setText(resourceMap.getString("openButton.text")); // NOI18N
        openButton.setToolTipText(resourceMap.getString("openButton.toolTipText")); // NOI18N
        openButton.setFocusable(false);
        openButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        openButton.setName("openButton"); // NOI18N
        openButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        openButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openButtonActionPerformed(evt);
            }
        });
        toolBar.add(openButton);

        saveButton.setIcon(resourceMap.getIcon("saveButton.icon")); // NOI18N
        saveButton.setText(resourceMap.getString("saveButton.text")); // NOI18N
        saveButton.setToolTipText(resourceMap.getString("saveButton.toolTipText")); // NOI18N
        saveButton.setFocusable(false);
        saveButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        saveButton.setName("saveButton"); // NOI18N
        saveButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });
        toolBar.add(saveButton);

        saveAsButton.setIcon(resourceMap.getIcon("saveAsButton.icon")); // NOI18N
        saveAsButton.setText(resourceMap.getString("saveAsButton.text")); // NOI18N
        saveAsButton.setToolTipText(resourceMap.getString("saveAsButton.toolTipText")); // NOI18N
        saveAsButton.setFocusable(false);
        saveAsButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        saveAsButton.setName("saveAsButton"); // NOI18N
        saveAsButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        saveAsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveAsButtonActionPerformed(evt);
            }
        });
        toolBar.add(saveAsButton);

        jSeparator5.setName("jSeparator5"); // NOI18N
        toolBar.add(jSeparator5);

        cutButton.setIcon(resourceMap.getIcon("cutButton.icon")); // NOI18N
        cutButton.setText(resourceMap.getString("cutButton.text")); // NOI18N
        cutButton.setToolTipText(resourceMap.getString("cutButton.toolTipText")); // NOI18N
        cutButton.setFocusable(false);
        cutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        cutButton.setName("cutButton"); // NOI18N
        cutButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        cutButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cutButtonActionPerformed(evt);
            }
        });
        toolBar.add(cutButton);

        copyButton.setIcon(resourceMap.getIcon("copyButton.icon")); // NOI18N
        copyButton.setText(resourceMap.getString("copyButton.text")); // NOI18N
        copyButton.setToolTipText(resourceMap.getString("copyButton.toolTipText")); // NOI18N
        copyButton.setFocusable(false);
        copyButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        copyButton.setName("copyButton"); // NOI18N
        copyButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        copyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                copyButtonActionPerformed(evt);
            }
        });
        toolBar.add(copyButton);

        pasteButton.setIcon(resourceMap.getIcon("pasteButton.icon")); // NOI18N
        pasteButton.setText(resourceMap.getString("pasteButton.text")); // NOI18N
        pasteButton.setToolTipText(resourceMap.getString("pasteButton.toolTipText")); // NOI18N
        pasteButton.setFocusable(false);
        pasteButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        pasteButton.setName("pasteButton"); // NOI18N
        pasteButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        pasteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pasteButtonActionPerformed(evt);
            }
        });
        toolBar.add(pasteButton);

        jSeparator6.setName("jSeparator6"); // NOI18N
        toolBar.add(jSeparator6);

        compileButton.setIcon(resourceMap.getIcon("compileButton.icon")); // NOI18N
        compileButton.setText(resourceMap.getString("compileButton.text")); // NOI18N
        compileButton.setToolTipText(resourceMap.getString("compileButton.toolTipText")); // NOI18N
        compileButton.setFocusable(false);
        compileButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        compileButton.setName("compileButton"); // NOI18N
        compileButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        compileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                compileButtonActionPerformed(evt);
            }
        });
        toolBar.add(compileButton);

        jSplitPane1.setDividerLocation(200);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setMaximumSize(new java.awt.Dimension(400, 200));
        jSplitPane1.setMinimumSize(new java.awt.Dimension(450, 200));
        jSplitPane1.setName("jSplitPane1"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        procesadorTextArea.setColumns(20);
        procesadorTextArea.setRows(5);
        procesadorTextArea.setMinimumSize(new java.awt.Dimension(20, 40));
        procesadorTextArea.setName("procesadorTextArea"); // NOI18N
        procesadorTextArea.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                procesadorTextAreaCaretUpdate(evt);
            }
        });
        procesadorTextArea.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                procesadorTextAreaKeyTyped(evt);
            }
        });
        jScrollPane1.setViewportView(procesadorTextArea);

        jSplitPane1.setTopComponent(jScrollPane1);

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        realimentacionTextArea.setColumns(20);
        realimentacionTextArea.setEditable(false);
        realimentacionTextArea.setRows(5);
        realimentacionTextArea.setFocusable(false);
        realimentacionTextArea.setMaximumSize(new java.awt.Dimension(400, 350));
        realimentacionTextArea.setName("realimentacionTextArea"); // NOI18N
        jScrollPane2.setViewportView(realimentacionTextArea);

        jSplitPane1.setRightComponent(jScrollPane2);

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 430, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(toolBar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 431, Short.MAX_VALUE))
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 286, Short.MAX_VALUE)
                .addContainerGap())
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        newMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        newMenuItem.setIcon(resourceMap.getIcon("newMenuItem.icon")); // NOI18N
        newMenuItem.setText(resourceMap.getString("newMenuItem.text")); // NOI18N
        newMenuItem.setToolTipText(resourceMap.getString("newMenuItem.toolTipText")); // NOI18N
        newMenuItem.setName("newMenuItem"); // NOI18N
        newMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(newMenuItem);

        openMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        openMenuItem.setIcon(resourceMap.getIcon("openMenuItem.icon")); // NOI18N
        openMenuItem.setText(resourceMap.getString("openMenuItem.text")); // NOI18N
        openMenuItem.setToolTipText(resourceMap.getString("openMenuItem.toolTipText")); // NOI18N
        openMenuItem.setName("openMenuItem"); // NOI18N
        openMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(openMenuItem);

        saveMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        saveMenuItem.setIcon(resourceMap.getIcon("saveMenuItem.icon")); // NOI18N
        saveMenuItem.setText(resourceMap.getString("saveMenuItem.text")); // NOI18N
        saveMenuItem.setToolTipText(resourceMap.getString("saveMenuItem.toolTipText")); // NOI18N
        saveMenuItem.setName("saveMenuItem"); // NOI18N
        saveMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveMenuItem);

        saveAsMenuItem.setIcon(resourceMap.getIcon("saveAsMenuItem.icon")); // NOI18N
        saveAsMenuItem.setText(resourceMap.getString("saveAsMenuItem.text")); // NOI18N
        saveAsMenuItem.setToolTipText(resourceMap.getString("saveAsMenuItem.toolTipText")); // NOI18N
        saveAsMenuItem.setName("saveAsMenuItem"); // NOI18N
        saveAsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveAsMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveAsMenuItem);

        jSeparator1.setName("jSeparator1"); // NOI18N
        fileMenu.add(jSeparator1);

        compileMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F6, 0));
        compileMenuItem.setIcon(resourceMap.getIcon("compileMenuItem.icon")); // NOI18N
        compileMenuItem.setText(resourceMap.getString("compileMenuItem.text")); // NOI18N
        compileMenuItem.setToolTipText(resourceMap.getString("compileMenuItem.toolTipText")); // NOI18N
        compileMenuItem.setName("compileMenuItem"); // NOI18N
        compileMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                compileMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(compileMenuItem);

        jSeparator2.setName("jSeparator2"); // NOI18N
        fileMenu.add(jSeparator2);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(interfaz.GraphSApp.class).getContext().getActionMap(GraphSView.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setIcon(resourceMap.getIcon("exitMenuItem.icon")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        jMenu1.setText(resourceMap.getString("jMenu1.text")); // NOI18N
        jMenu1.setName("jMenu1"); // NOI18N

        cutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK));
        cutMenuItem.setIcon(resourceMap.getIcon("cutMenuItem.icon")); // NOI18N
        cutMenuItem.setText(resourceMap.getString("cutMenuItem.text")); // NOI18N
        cutMenuItem.setName("cutMenuItem"); // NOI18N
        cutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cutMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(cutMenuItem);

        copyMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK));
        copyMenuItem.setIcon(resourceMap.getIcon("copyMenuItem.icon")); // NOI18N
        copyMenuItem.setText(resourceMap.getString("copyMenuItem.text")); // NOI18N
        copyMenuItem.setName("copyMenuItem"); // NOI18N
        copyMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                copyMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(copyMenuItem);

        pasteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_MASK));
        pasteMenuItem.setIcon(resourceMap.getIcon("pasteMenuItem.icon")); // NOI18N
        pasteMenuItem.setText(resourceMap.getString("pasteMenuItem.text")); // NOI18N
        pasteMenuItem.setName("pasteMenuItem"); // NOI18N
        pasteMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pasteMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(pasteMenuItem);

        deleteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0));
        deleteMenuItem.setIcon(resourceMap.getIcon("deleteMenuItem.icon")); // NOI18N
        deleteMenuItem.setText(resourceMap.getString("deleteMenuItem.text")); // NOI18N
        deleteMenuItem.setName("deleteMenuItem"); // NOI18N
        deleteMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(deleteMenuItem);

        jSeparator4.setName("jSeparator4"); // NOI18N
        jMenu1.add(jSeparator4);

        selectAllMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK));
        selectAllMenuItem.setText(resourceMap.getString("selectAllMenuItem.text")); // NOI18N
        selectAllMenuItem.setName("selectAllMenuItem"); // NOI18N
        selectAllMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectAllMenuItemActionPerformed(evt);
            }
        });
        jMenu1.add(selectAllMenuItem);

        menuBar.add(jMenu1);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        userManualMenuItem.setIcon(resourceMap.getIcon("userManualMenuItem.icon")); // NOI18N
        userManualMenuItem.setText(resourceMap.getString("userManualMenuItem.text")); // NOI18N
        userManualMenuItem.setName("userManualMenuItem"); // NOI18N
        userManualMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                userManualMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(userManualMenuItem);

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setIcon(resourceMap.getIcon("aboutMenuItem.icon")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 451, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 222, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
        setToolBar(toolBar);
    }// </editor-fold>//GEN-END:initComponents

    private void newMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newMenuItemActionPerformed
        int op = CANCEL_OP;
        if (grafoModificado) {
            op = confirmDialog();
            if (op == YES_OP) saveGraph();
            else if (op == NO_OP) newGraph();
        }
        else {
            newGraph();
        }
    }//GEN-LAST:event_newMenuItemActionPerformed

    private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMenuItemActionPerformed
        int op = CANCEL_OP;
        if (grafoModificado) {
            op = confirmDialog();
            if (op == YES_OP) saveGraph();
            else if (op == NO_OP) openGraph();
        }
        else {
            openGraph();
        }
    }//GEN-LAST:event_openMenuItemActionPerformed

    private void saveMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveMenuItemActionPerformed
        saveGraph();
    }//GEN-LAST:event_saveMenuItemActionPerformed

    private void compileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_compileButtonActionPerformed
        int op = CANCEL_OP;
        if (grafoModificado) {
            op = confirmDialog();
            if (op == YES_OP) {
                saveGraph();
                compileGraph();
            }
            else if (op == NO_OP) compileGraph();
        }
        else {
            compileGraph();
        }
    }//GEN-LAST:event_compileButtonActionPerformed

    private void compileMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_compileMenuItemActionPerformed
        int op = CANCEL_OP;
        if (grafoModificado) {
            op = confirmDialog();
            if (op == YES_OP) {
                saveGraph();
                compileGraph();
            }
            else if (op == NO_OP) compileGraph();
        }
        else {
            compileGraph();
        }
    }//GEN-LAST:event_compileMenuItemActionPerformed

    private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed
        int op = CANCEL_OP;
        if (grafoModificado) {
            op = confirmDialog();
            if (op == YES_OP) saveGraph();
            else if (op == NO_OP) newGraph();
        }
        else {
            newGraph();
        }
    }//GEN-LAST:event_newButtonActionPerformed

    private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
        int op = CANCEL_OP;
        if (grafoModificado) {
            op = confirmDialog();
            if (op == YES_OP) saveGraph();
            else if (op == NO_OP) openGraph();
        }
        else {
            openGraph();
        }
    }//GEN-LAST:event_openButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        saveGraph();
    }//GEN-LAST:event_saveButtonActionPerformed

    private void procesadorTextAreaKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_procesadorTextAreaKeyTyped
        if (!grafoModificado && !evt.isControlDown()) {
            grafoModificado = true;
            String currentTitle = GraphSApp.getApplication().getMainFrame().getTitle();
            GraphSApp.getApplication().getMainFrame().setTitle(currentTitle + " *");
        }
    }//GEN-LAST:event_procesadorTextAreaKeyTyped

    private void saveAsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsButtonActionPerformed
        saveAsGraph();
    }//GEN-LAST:event_saveAsButtonActionPerformed

    private void saveAsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveAsMenuItemActionPerformed
        saveAsGraph();
    }//GEN-LAST:event_saveAsMenuItemActionPerformed

    private void cutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cutButtonActionPerformed
        procesadorTextArea.cut();
    }//GEN-LAST:event_cutButtonActionPerformed

    private void cutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cutMenuItemActionPerformed
        procesadorTextArea.cut();
    }//GEN-LAST:event_cutMenuItemActionPerformed

    private void copyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyButtonActionPerformed
        procesadorTextArea.copy();
    }//GEN-LAST:event_copyButtonActionPerformed

    private void copyMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyMenuItemActionPerformed
        procesadorTextArea.copy();
    }//GEN-LAST:event_copyMenuItemActionPerformed

    private void pasteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pasteButtonActionPerformed
        String before = procesadorTextArea.getText();
        procesadorTextArea.paste();
        if (!before.equals(procesadorTextArea.getText())) {
            if (!grafoModificado) {
                grafoModificado = true;
                String currentTitle = GraphSApp.getApplication().getMainFrame().getTitle();
                GraphSApp.getApplication().getMainFrame().setTitle(currentTitle + " *");
            }
        }
    }//GEN-LAST:event_pasteButtonActionPerformed

    private void pasteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pasteMenuItemActionPerformed
        String before = procesadorTextArea.getText();
        procesadorTextArea.paste();
        if (!before.equals(procesadorTextArea.getText())) {
            if (!grafoModificado) {
                grafoModificado = true;
                String currentTitle = GraphSApp.getApplication().getMainFrame().getTitle();
                GraphSApp.getApplication().getMainFrame().setTitle(currentTitle + " *");
            }
        }
    }//GEN-LAST:event_pasteMenuItemActionPerformed

    private void selectAllMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllMenuItemActionPerformed
        procesadorTextArea.selectAll();
    }//GEN-LAST:event_selectAllMenuItemActionPerformed

    private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteMenuItemActionPerformed
        procesadorTextArea.setText(procesadorTextArea.getText().substring(0, procesadorTextArea.getSelectionStart()-1) + procesadorTextArea.getText().substring(procesadorTextArea.getSelectionEnd(), procesadorTextArea.getText().length()));
    }//GEN-LAST:event_deleteMenuItemActionPerformed

    private void userManualMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_userManualMenuItemActionPerformed
        String nombreSO = System.getProperty("os.name");
        String url = "file:" + System.getProperty("user.dir") + "/UserManual/index.html";
        try {
            if (nombreSO.startsWith("Windows"))
                Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
            else{
                //se asume  Unix or Linux
                String[] navegadores = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
                String navegador = null;
                for (int contador = 0; contador < navegadores.length && navegador == null; contador++){
                    if (Runtime.getRuntime().exec( new String[] {"which", navegadores[contador]}).waitFor() == 0)
                        navegador = navegadores[contador];
                }

                if (navegador == null) realimentacionTextArea.append("No se encuentra navegador web.\n");
                else
                    Runtime.getRuntime().exec(new String[] {navegador, url});
                }
        } catch (Exception ex) {
            realimentacionTextArea.append("Error al intentar lanzar el navegador web.\n"+ex.getMessage());
        }
        
}//GEN-LAST:event_userManualMenuItemActionPerformed

    private void procesadorTextAreaCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_procesadorTextAreaCaretUpdate
        // TODO add your handling code here:
        int pos = evt.getDot();
        int row, col;
        try {
            row = procesadorTextArea.getLineOfOffset(pos) + 1;
            col = pos - procesadorTextArea.getLineStartOffset( row - 1 ) + 1;
            statusMessageLabel.setText(row+":"+col);
        } catch (BadLocationException ex) {
            Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_procesadorTextAreaCaretUpdate

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton compileButton;
    private javax.swing.JMenuItem compileMenuItem;
    private javax.swing.JButton copyButton;
    private javax.swing.JMenuItem copyMenuItem;
    private javax.swing.JButton cutButton;
    private javax.swing.JMenuItem cutMenuItem;
    private javax.swing.JMenuItem deleteMenuItem;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JToolBar.Separator jSeparator5;
    private javax.swing.JToolBar.Separator jSeparator6;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JToggleButton jToggleButton1;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JButton newButton;
    private javax.swing.JMenuItem newMenuItem;
    private javax.swing.JButton openButton;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JButton pasteButton;
    private javax.swing.JMenuItem pasteMenuItem;
    private javax.swing.JTextArea procesadorTextArea;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JTextArea realimentacionTextArea;
    private javax.swing.JButton saveAsButton;
    private javax.swing.JMenuItem saveAsMenuItem;
    private javax.swing.JButton saveButton;
    private javax.swing.JMenuItem saveMenuItem;
    private javax.swing.JMenuItem selectAllMenuItem;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JToolBar toolBar;
    private javax.swing.JMenuItem userManualMenuItem;
    // End of variables declaration//GEN-END:variables

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;
    private JDialog visorBox;

    public void setRealimentacionTextArea (String message) {
        realimentacionTextArea.append(message + '\n');
    }

    public void newGraph () {
        procesadorTextArea.setText("");
        realimentacionTextArea.setText("");
        grafoModificado = false;
        GraphSApp.getApplication().getMainFrame().setTitle(title + "Untitled");
        fileGraph = null;
        realimentacionTextArea.append("New graph...\n");
    }

    public int openGraph () {
        int res = NO_OP;
        JFileChooser fcAbrir = new JFileChooser();
        fcAbrir.addChoosableFileFilter(new FiltreSimple());
        fcAbrir.setDialogTitle("Open");

        int valorDevuelto = fcAbrir.showOpenDialog(null);
        //Recoger el nombre del fichero seleccionado por el usuario
        if (valorDevuelto == JFileChooser.APPROVE_OPTION) {
            res = YES_OP;
            BufferedReader br = null;
            try {
                File file = fcAbrir.getSelectedFile();
                procesadorTextArea.setText("");
                realimentacionTextArea.setText("Opening " + file.getAbsolutePath() + " ...\n");
                br = new BufferedReader(new FileReader(file));
                String line = br.readLine();
                while (line != null) {
                    procesadorTextArea.append(line + '\n');
                    line = br.readLine();
                }
                br.close();
                realimentacionTextArea.append("Graph opened." + '\n');
                grafoModificado = false;
                GraphSApp.getApplication().getMainFrame().setTitle(title + file.getName());
                fileGraph = file;
            } catch (FileNotFoundException ex) {
                Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    br.close();
                } catch (IOException ex) {
                    Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return res;
    }

    public int saveGraph () {
        int res = CANCEL_OP;
        if (fileGraph == null){
            res = saveAsGraph();
        }
        else {
            BufferedWriter bw = null;
            try {
                res = YES_OP;
                System.out.println(fileGraph.getName());
                bw = new BufferedWriter(new FileWriter(fileGraph));
                bw.write(procesadorTextArea.getText());
                realimentacionTextArea.append("Graph saved as " + fileGraph + '\n');
                grafoModificado = false;
                GraphSApp.getApplication().getMainFrame().setTitle(title + fileGraph.getName());
            } catch (IOException ex) {
                Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    bw.close();
                } catch (IOException ex) {
                    Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return res;
    }

    public int saveAsGraph(){
        int res = NO_OP;
        JFileChooser fcGuardar = new JFileChooser();
        FiltreSimple graph = new FiltreSimple();
        fcGuardar.addChoosableFileFilter(graph);
        fcGuardar.setFileFilter(graph);
        fcGuardar.setDialogTitle("Save as");

        int valorDevuelto = fcGuardar.showSaveDialog(null);
        if (valorDevuelto == JFileChooser.APPROVE_OPTION) {
            BufferedWriter bw = null;
            try {
                res = YES_OP;
                File file = fcGuardar.getSelectedFile();
                String fileName = file.getAbsolutePath();
                System.out.println(fileName);
                if (!fileName.endsWith(graph.getExtension())){
                    fileName = fileName + graph.getExtension();
                }
                System.out.println(fileName);
                file = new File(fileName);
                System.out.println(file.getName());
                bw = new BufferedWriter(new FileWriter(file));
                bw.write(procesadorTextArea.getText());
                realimentacionTextArea.append("Graph saved as " + file + '\n');
                grafoModificado = false;
                GraphSApp.getApplication().getMainFrame().setTitle(title + file.getName());
                fileGraph = file;
            } catch (IOException ex) {
                Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    bw.close();
                } catch (IOException ex) {
                    Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return res;
    }

    public void compileGraph() {
        parser parser_obj = null;
        ArrayList<Graph> grafos = null;
        String msg = "";
        boolean compiled = false;
        if (!realimentacionTextArea.getText().equals("")) msg += "---\n";
        try {
            if (!procesadorTextArea.getText().equals("")) {
                if (!grafoModificado) {
                    parser_obj = new parser(new AnaLex(new FileReader(fileGraph.getAbsolutePath())));
                    msg += "Compiling file " + fileGraph.getName() + " ...\n";
                }
                else {
                    InputStream is = new ByteArrayInputStream(procesadorTextArea.getText().getBytes("UTF-8"));
                    parser_obj = new parser(new AnaLex(is));
                    msg += "Compiling current graph...\n";
                }
                parser_obj.parse();
                grafos = parser_obj.getGrafos();
                compiled = true;
            }
            else {
                msg += "Error: cannot compile an empty graph";
            }

            if (compiled) {
                realimentacionTextArea.append(msg + parser_obj.getMensajes());
                parser_obj.clearMensajes();
            }
            else {
                realimentacionTextArea.append("There is nothing to compile.\n");
            }
        } catch (Exception ex) {
            Logger.getLogger(GraphSView.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (grafos != null && grafos.size() > 0) {
            Result r = Result.getInstance();
            if (grafoModificado) {
                r.creaGrafos(grafos, "Current graph");
            }
            else {
                r.creaGrafos(grafos, fileGraph.getName());
            }
            realimentacionTextArea.append(r.getMessages());
            r.clearMessages();
            realimentacionTextArea.append("Done. " + r.getGrafosCreados() + " graphs compiled.\n");
        }
    }

    public int confirmDialog() {
        int res = CANCEL_OP;
        int resp = JOptionPane.showConfirmDialog(GraphSApp.getApplication().getMainFrame(), "Current graph has not been saved yet. Do you want to save it now?", "GraphS", JOptionPane.YES_NO_CANCEL_OPTION);
        if (resp == JOptionPane.YES_OPTION)
            res = saveGraph();
        else if (resp == JOptionPane.NO_OPTION)
            res = NO_OP;
        else if (resp == JOptionPane.CANCEL_OPTION)
            res = CANCEL_OP;
        return res;
    }
}
